require 'will_paginate'

class ItemsController < ApplicationController
  before_filter :except => [:item_attributes, :comments, :cap_color, :by_barcode,
    :bag_contents_by_barcode, :bag_contents, :show, :barcode, :lookup, :update] do |controller|
	controller.authorize_permissions({:blocked_permissions => ["courier"]})
  end

  def comments
    @comments = Item.find_by_id(params["id"]).comments
    respond_to do |format|
      format.json { render :json => @comments }
    end
  end
  
  def item_attributes
      @attributes = Item.find_by_id(params["id"]).item_attributes
      respond_to do |format|
        format.json { render :json => @attributes }
      end
  end  
  
  def cap_color
    @item = Item.find_by_id(params["id"])
    @color_id = ItemAttributeSet.find_by_name("Color").id
    @color = @item.item_attributes.find_by_item_attribute_set_id(@color_id)
    respond_to do |format|
      format.json { render :json => [@color] }
    end
  end
  
  def by_barcode
    @item = Identifier.find_by_identifier_value(params["id"]).item
    respond_to do |format|
      format.json { render :json => [@item] }
    end
  end
  
  def bag_contents_by_barcode
    @bag = Identifier.find_by_identifier_value(params["id"]).item
    respond_to do |format|
      format.json { render :json => @bag.contained_items }
    end
  end
  
  def bag_contents
    @bag = Item.find_by_id(params["id"])
    respond_to do |format|
      format.json { render :json => @bag.contained_items }
    end
  end

  def filter(title, items, params)
    @filter_by = ""
    if params[:item_types] && params[:item_types][:id] && params[:item_types][:id] != ""
      @items_t = Item.find_all_by_item_type_id(params[:item_types][:id])
      @item_type = ItemType.find(params[:item_types][:id])
      @filter_by += " '" + @item_type.item_type + "'"
      flag_t = true
      @item_types = ItemType.find_by_id(params[:item_types][:id])
    else
      flag_t = false
    end
    
    if params[:status] && params[:status] != ""
      @items_s = Array.new
      Item.all.each do |item|
        @checkins = CheckIn.find_all_by_item_id(item.id, :order => "created_at DESC")
        if @checkins.first && @checkins.first.action == params[:status]
          @items_s << item
        end
      end
      if params[:status] == 'initial_checkin'
        @status = "Waiting Pickup"
      elsif params[:status] == 'pick_up'
        @status = "In transit"
      elsif params[:status] == 'drop_off'
        @status = "Delivered"
      else
        @status = "Unknown"
      end
      @filter_by += " '" + @status + "'"
      flag_s = true
      @status = params[:status]
    else
      flag_s = false
    end
    
    if params[:item_attributes] && params[:item_attributes][:id] && params[:item_attributes][:id] != ""
      @items_a = Array.new
      @attribute = ItemAttribute.find(params[:item_attributes][:id])
      @attribute_values = @attribute.item_attribute_values
      @attribute_values.each do |attribute_value|
        @items_a << attribute_value.item
      end
      @filter_by += " '" + @attribute.display_text + "'"
      flag_a = true
      @item_attributes = ItemAttribute.find_by_id(params[:item_attributes][:id])
    else
      flag_a = false
    end
    
    items = items.find_all{|item|
      ((!flag_t) || @items_t.include?(item)) &&
      ((!flag_s) || @items_s.include?(item)) &&
      ((!flag_a) || @items_a.include?(item))
    }

    if @filter_by != ""
      title += ":" + @filter_by
    end
    return title, items
  end
  
  # GET /items
  # GET /items.json
  def index
    
    @title, @items = filter("All Items", Item.find(:all, :order => "created_at DESC"), params)
    
    @page_results = @items.paginate(:page => params[:page], :per_page => 10)
    
    respond_to do |format|
      format.html # index.html.erb
      format.json  { render :json => @items }
    end
  end 

  def barcode
    @item = Item.find(params[:id])
    @barcode = @item.identifiers.first
    @children = Item.find_all_by_contained_by_id(@item.id)
    @children_barcodes = Array.new
    @children.each do |child|
      @children_barcodes << child.identifiers.first.identifier_value
    end
    @title = "Barcode: " + @barcode.identifier_value
		
    respond_to do |format|
      format.html 
      format.json { render :json => [@barcode]}
    end
  end
 
  def incoming
    @user = User.find_by_id(session[:user_id])
    @title, @items = filter("Incoming Items", Item.find_all_by_destination_id_and_delivered(@user.location.id, false, :order => "created_at DESC"), params)
  
    @page_results = @items.paginate(:page => params[:page], :per_page => 10)
  end
 
  def outgoing
    @user = User.find_by_id(session[:user_id])
    @title, @items = filter("Outgoing Items", Item.find_all_by_source_id_and_delivered(@user.location.id, false, :order => "created_at DESC"), params)
  
    @page_results = @items.paginate(:page => params[:page], :per_page => 10)
  end
  
  def lookup
    @defaultTitle = "Lookup Items"
    if params[:q]
      @identifier = Identifier.find_by_identifier_value(params[:q])
      if @identifier.nil?
        flash_msg = "Identifier \"#{params[:q]}\" not found"
        flash.now[:notice] = flash_msg
        @title = @defaultTitle
        render 'lookup'
      else
		@item = @identifier.item
		@type = @item.item_type
		@item_type = (@type)?(@type.item_type):("No Type")
		@identifier = @item.identifiers.first
		generate_container(@item)
		@title = @item.display_name

        render 'lookup-item'
      end
    else
      @title = @defaultTitle
      render 'lookup'
    end
  end
  
  # GET /items/1
  # GET /items/1.json
  def show
    @item = Item.find(params[:id])

    @type = @item.item_type
    @item_type = (@type)?(@type.item_type):("No Type")

    @identifier = @item.identifiers.first

	generate_container(@item)
	
	@title = @item.display_name
		
    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json => [@item] }
    end
  end

  # GET /items/1/add_to_container
  # GET /items/1/add_to_container.json
  def add_to_container
    @item = Item.find(params[:id])
    @type = @item.item_type
    @item_type = (@type)?(@type.item_type):("No Type")

	@identifier = @item.identifiers.first
	@title = "Add to " + @item.display_name
	
	# Start with no existing items
	@existing_items = []
	# Start with no new items
	@new_items = []
  end
  
  helper_method :populate_new_item
  def populate_new_item(in_container)
	  new_item = Item.new
	  new_item.comments << Comment.new
	  new_item.identifiers << Identifier.new

	  # add set attributes that need to so can use fields_for
	  attribute_sets = ItemAttributeSet.all
	  attribute_sets.each do |attribute_set|
		  if attribute_set.item_attributes.first
			if not (in_container and attribute_set.inherits_from_container)
			  if attribute_set.mutually_exclusive
				  new_item.item_attribute_values << ItemAttributeValue.new
			  else
				  attribute_set.item_attributes.each do |attr|
					  new_item.item_attribute_values << ItemAttributeValue.new
				  end
			  end
			end
		  end
	  end
	  
	  new_item
  end
  
  # GET /items/new
  # GET /items/new.json
  def new
    @title = "New Item"
    @item = populate_new_item(false)
	
    respond_to do |format|
      format.html # new.html.erb
      format.json  { render :json => @item }
    end
  end

  # POST /items
  # POST /items.json
  def create
    @item = Item.new(params[:item])
	respond_to do |format|
	  if @item.save
		flash[:notice] = 'Item was successfully created.'
		format.html { redirect_to items_path }
		format.json  { render :json => @item, :status => :created, :location => @item }
	  else
		if @item.comments.empty?
		  # Adds comment back if was deleted in validation
		  @item.comments << Comment.new
		end
		
		@title = "New Item"
		format.html { render :action => "new" }
		format.json  { render :json => @item.errors, :status => :unprocessable_entity }
	  end
	end
  end

  helper_method :add_existing
  def add_existing(i, existing_counter)
	if i[:id].to_s
		res = Item.find_by_id(i[:id])
		@existing_items << res
		if res
			@item.contained_items << res
		else
			@item.errors.add_to_base("Item doesn't exist " + res.to_s)
		end
		existing_counter = existing_counter + 1
	end
  end
  
  # PUT /items/1
  # PUT /items/1.json
  def update
    @item = Item.find_by_id(params[:id])
	if params[:commit] == "Remove"
	  remove_item
	elsif params[:commit] == "Add Items"
	  add_item_to_container
	elsif params[:commit] == "Comment"
	  add_comment
	else
	  #render :controller
	end
  end

  # DELETE /items/1
  # DELETE /items/1.json
  def destroy
    @item = Item.find(params[:id])
    @item.destroy

    respond_to do |format|
      format.html { redirect_to(items_url) }
      format.json  { head :ok }
    end
  end
  
private
  def remove_item
	@item.contained_by_id = nil
	
	respond_to do |format|
	  if @item.save
        flash[:notice] = 'Item was successfully removed from container.'
		format.html { redirect_to :back }
	  else
		flash[:notice] = 'Could not update item.'

		@type = @item.item_type
		@item_type = (@type)?(@type.item_type):("No Type")
		@identifier = @item.identifiers.first
		generate_container(@item)
		@title = @item.display_name

		format.html { render 'show' }
	  end
	end
  end
  
  def add_item_to_container
	@request_existing = params[:existing_items]
	@existing_items = []
	if @request_existing
		existing_counter = 0
		if @request_existing.is_a? Array
			@request_existing.each do |i|
				add_existing(i, existing_counter)
			end
		elsif @request_existing.is_a? Hash
			@request_existing.each_value do |i|
				add_existing(i, existing_counter)
			end
		end
	end
	

	@request_new = params[:new_items]
	@new_items = []
	if @request_new
		new_counter = 0
		@request_new.each do |i|
			@new_items << Item.new(i)
			@item.contained_items << @new_items[new_counter]
			new_counter = new_counter + 1
		end
	end

	respond_to do |format|
	  if @item.save
		flash[:notice] = 'Items were successfully added to container.'
		format.html { redirect_to item_path(@item) }
	  else
		flash[:notice] = 'Could not update item.'

		@type = @item.item_type
		@item_type = (@type)?(@type.item_type):("No Type")
		@identifier = @item.identifiers.first
		generate_container(@item)
		@title = @item.display_name

		format.html { render 'add_to_container' }
	  end
	end
  end
  
  def add_comment
	@comment = Comment.new(params[:comment])

	respond_to do |format|
	  if @comment.save
		flash[:notice] = 'Added Comment to Item.'
		format.html { redirect_to :back }
	  else
		flash[:notice] = 'Could not add comment. Make sure it is a valid comment.'

		@type = @item.item_type
		@item_type = (@type)?(@type.item_type):("No Type")
		@identifier = @item.identifiers.first
		generate_container(@item)
		@title = @item.display_name

		format.html { render 'show' }
	  end
	end
  end
end
